﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.Specialized;
using System.Globalization;
using Barbar.MapReport.Common;
using System.Collections.ObjectModel;
using Barbar.MapReport.DataSource;

namespace Barbar.MapReport.HtmlRender.Handlers {
  internal class MapCallbackData {
    private GeoBound m_GeoBound;
    private int m_GoogleZoomLevel;
    private ZoomLevel m_ZoomLevel;
    private Dictionary<string, string> m_ServerCallbackData = new Dictionary<string, string>();
    private string m_CallbackId;
    private string m_HandlerUrl;

    public ICollection<string> Keys {
      get { return m_ServerCallbackData.Keys; }
    }

    public string CallbackId {
      get { return m_CallbackId; }
    }

    public GeoBound GeoBound {
      get { return m_GeoBound; }
    }

    public int GooleZoomLevel {
      get { return m_GoogleZoomLevel; }
    }

    public ZoomLevel ZoomLevel {
      get { return m_ZoomLevel; }
    }

    public string HandlerUrl {
      get { return m_HandlerUrl; }
    }

    public bool ContainsKey(string key) {
      return m_ServerCallbackData.ContainsKey(key);
    }

    public string this[string key] {
      get { return m_ServerCallbackData[key]; }
    }

    private MapCallbackData(string callbackId, GeoBound geoBound, int googleZoomLevel, string handlerUrl, Dictionary<string, string> serverCallbackData) {
      m_CallbackId = callbackId;
      m_GeoBound = geoBound;
      m_GoogleZoomLevel = googleZoomLevel;
      m_ZoomLevel = DataSourceManager.ZoomLevels.GetZoomLevel(m_GoogleZoomLevel);
      m_HandlerUrl = handlerUrl;
      m_ServerCallbackData = serverCallbackData;
    }

    public static MapCallbackData CreateMapCallbackData(NameValueCollection values) {
      if (values == null)
        throw new ArgumentNullException("values");

      int zoom = Convert.ToInt32(values["zoom"], CultureInfo.InvariantCulture);
      decimal swLat = Convert.ToDecimal(values["swLat"], CultureInfo.InvariantCulture);
      decimal swLng = Convert.ToDecimal(values["swLng"], CultureInfo.InvariantCulture);
      decimal neLat = Convert.ToDecimal(values["neLat"], CultureInfo.InvariantCulture);
      decimal neLng = Convert.ToDecimal(values["neLng"], CultureInfo.InvariantCulture);
      string handlerUrl = values["handlerUrl"];
      
      GeoBound viewBound = new GeoBound(new GeoPoint(neLat, neLng), new GeoPoint(swLat, swLng));
      Dictionary<string, string> serverCallbackData = new Dictionary<string, string>();
      for (int i = 0; i < values.Count; i++) {
        string key = values.AllKeys[i];

        if (!key.StartsWith("key", StringComparison.Ordinal))
          continue;

        key = key.Substring(3);
        string value = values[i];
        
        serverCallbackData.Add(key, value);
      }

      return new MapCallbackData(values["callbackId"], viewBound, zoom, handlerUrl, serverCallbackData);
    }
  }
}
